package com.fast.alden.admin.service.impl;

import com.fast.alden.admin.service.SysPositionService;
import com.fast.alden.admin.service.SysUserService;
import com.fast.alden.common.service.impl.BaseEntityServiceImpl;
import com.fast.alden.data.model.SysPosition;
import com.fast.alden.data.model.SysUser;
import com.fast.alden.data.model.SysUserPosition;
import com.fast.alden.data.repo.SysPositionRepository;
import com.fast.alden.data.repo.SysUserPositionRepository;
import jakarta.annotation.Resource;
import jakarta.transaction.Transactional;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class SysPositionServiceImpl extends BaseEntityServiceImpl<SysPosition, SysPositionRepository> implements SysPositionService {
    @Resource
    private SysPositionRepository repository;
    @Resource
    private SysUserPositionRepository userPositionRepository;
    @Resource
    private SysUserService userService;

    @Override
    protected Class<SysPosition> getEClass() {
        return SysPosition.class;
    }

    @Override
    protected SysPositionRepository getRepository() {
        return repository;
    }

    @Override
    @Transactional
    public List<SysPosition> remove(List<Long> ids) {
        List<SysPosition> positions = super.remove(ids);

        // 删除用户-岗位关联数据
        userPositionRepository.deleteByPositionIdIn(ids);

        return positions;
    }

    @Override
    @Transactional
    public void assign(Long userId, List<Long> positionIds) {
        SysUser user = userService.retrieveWithException(userId);

        List<SysUserPosition> existUserPositions = userPositionRepository.findAllByUserIdIsAndPositionIdIn(userId, positionIds);
        List<Long> existPositionIds = existUserPositions.stream().map(SysUserPosition::getPositionId).toList();

        List<Long> toAddPositionIds = positionIds.stream().filter(it -> !existPositionIds.contains(it)).toList();

        if (toAddPositionIds.isEmpty()) {
            return;
        }

        List<SysUserPosition> toAddUserPositions = toAddPositionIds.stream().map(it -> {
            SysUserPosition userPosition = new SysUserPosition();
            userPosition.setUserId(userId);
            userPosition.setPositionId(it);
            return userPosition;
        }).toList();

        userPositionRepository.saveAll(toAddUserPositions);
    }

    @Override
    @Transactional
    public void cancelAssign(Long userId, List<Long> positionIds) {
        SysUser user = userService.retrieveWithException(userId);

        List<SysUserPosition> existUserPositions = userPositionRepository.findAllByUserIdIsAndPositionIdIn(userId, positionIds);

        if (existUserPositions.isEmpty()) {
            return;
        }

        userPositionRepository.deleteAll(existUserPositions);
    }

    @Override
    public List<SysPosition> findAllByUserId(Long userId) {
        List<SysUserPosition> userRoles = userPositionRepository.findAllByUserIdIs(userId);
        List<Long> positionIds = userRoles.stream().map(SysUserPosition::getPositionId).toList();
        return repository.findAllById(positionIds);
    }

    @Override
    public List<SysPosition> findPositionsByUserId(Long userId) {
        List<SysUserPosition> userRoles = userPositionRepository.findAllByUserIdIs(userId);
        List<Long> positionIds = userRoles.stream().map(SysUserPosition::getPositionId).toList();
        return list(positionIds);
    }
}
